#ifndef __SYSCALLS_H__
#define __SYSCALLS_H__

#undef  NULL
#define NULL	 0
#define EOF	 (-1)
#define BUFSIZ	 1024
#define OPEN_MAX 20		// max #files open at once
#define PERMS 	 0666
#define SEEK_SET 0		// 标准库中表示偏移起始位置为文件头
#define SEEK_CUR 1		// 标准库中表示偏移起始位置为当前位置
#define SEEK_END 2		// 标准库中表示偏移起始位置为文件尾

struct _flags
{
	unsigned int _READ  : 1;	// 只读
	unsigned int _WRITE : 1;	// 只写
	unsigned int _UNBUF : 1;	// 无缓冲
	unsigned int _EOF   : 1;	// 文件结尾
	unsigned int _ERR   : 1;	// 错误
};

typedef struct _iobuf 
{
	int cnt;		// 缓冲区剩余字符数
	char *ptr;		// 指向缓冲区下一字符的指针
	char *base;		// 指向缓冲区首字符的指针
	struct _flags flag;	// 文件模式
	int fd;			// 文件描述符
}FILE;

extern FILE _iob[OPEN_MAX];

#define stdin	 (&_iob[0])
#define stdout	 (&_iob[1])
#define stderr 	 (&_iob[2])

#define feof(p) 	(((p)->flag._EOF) != 0)
#define ferror(p)	(((p)->flag._ERR) != 0)
#define fileno(p)	((p)->fd)

// 刚开始执行时，缓冲区剩余字符数为0，调用_fillbuf将文件的数据读取到缓冲区，然后每次返回一个字符
#define fgetc(p)	(--(p)->cnt >= 0	\
		 ? (unsigned char) *(p)->ptr++ : _fillbuf(p))
// 刚开始执行时，缓冲区剩余字符数为0，调用_flushbuf分配缓冲区，然后每次写入一个字符到缓冲区，直到cnt为0，
// 调用_flushbuf将缓冲区写入文件中
#define fputc(x, p)	(--(p)->cnt >= 0	\
		 ? *(p)->ptr++ = (x) : _flushbuf((x), p))

#define getc() 	fgetc(stdin)
#define putc(x)	fputc((x), stdout)

FILE *fopen(const char *, const char *);
int _fillbuf(FILE *);		// _fillbuf填充缓冲区，将文件的数据读取到缓冲区中
int _flushbuf(int, FILE *);	// _flushbuf冲刷缓冲区，将缓冲区的数据写入到参数指定的文件中
int fflush(FILE *);		// fflush函数强迫将缓冲区内的数据写回参数指定的文件中，
				// 如果参数为NULL,fflush()会将所有打开文件数据更新
int fclose(FILE *);		// fclose函数关闭一个文件流，并释放文件指针和相关的缓冲区
int fseek(FILE *, long, int);

#endif
